﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Crawl.Common;
using Crawl.Common.Interface;
using Crawl.Common.Model;
using Idefav.DbFactory;
using Idefav.IDAL;
using Idefav.Utility;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace CrawlServices.BusinessTask
{
    public class MiniAppTask : TaskBase
    {
        public MiniAppTaskModel OModel { get { return base.Model as MiniAppTaskModel; } }
        public CancellationToken CancellationToken { get; set; }
        public IDbObject Db { get; set; }

        public string sTCookies = "";
        public static Random rd = new Random();
        public MiniAppTask(ITaskModel taskModel) : base(taskModel)
        {
            Db = DBOMaker.CreateDbObj(DBType.SQLServer, AppSettings.COMMONSETTINGS.DbMiniApp);
        }

        private string GetUserAgent()
        {
            string[] ualist = new[]
            {
                "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
                "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
                "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0",
                "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)",
                "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
                "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
                "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
                "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
                "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11",
                "Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11",
                "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
                "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0)",
                "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)",
                "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)",
                "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; The World)",
                "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)",
                "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)",
                "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Avant Browser)",
                "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
            };
            int d = rd.Next(ualist.Length);
            return ualist[d];
        }

        public override void Run(TaskScheduler taskScheduler, CancellationToken token)
        {
            this.CancellationToken = token;

            Task = new Task<object>(() =>
            {
                try
                {
                    Business();
                    NextStartTime = DateTime.Now.AddSeconds(OModel.Interval);
                    //Common.UpdateCrawlStatus(TmallTaskModel.TaskName, true);
                    CrawlServices.Business.UpdateCrawlComplete(OModel.TaskName);
                }
                catch (Exception e)
                {
                    Crawl.Common.Common.Log.LogError(e.ToString());
                }
                return null;
            }, token);
            Task.Start(taskScheduler);
        }

        private void Business()
        {
            HtmlHttpHelper HHH = new HtmlHttpHelper();
            HHH.Referer = "https://minapp.com/miniapp/";
            HHH.UserAgent = GetUserAgent();
            int pagesize = 12;
            int pageindex = 0;
            int offset = pagesize * pageindex;
            var html = HHH.Get(string.Format(OModel.ApiUrl, offset), "");
            HybridDictionary hybrid = JsonConvert.DeserializeObject<HybridDictionary>(html);
            var meta = hybrid["meta"] as JObject;
            var totalcount = meta["total_count"].Value<int>();
            pagesize = meta["limit"].Value<int>();
            var pagecount = totalcount / pagesize + (totalcount % pagesize != 0 ? 1 : 0);
            for (int i = 0; i < pagecount; i++)
            {
                HHH.UserAgent = GetUserAgent();
                html = HHH.Get(string.Format(OModel.ApiUrl, pagesize * i), "");
                var list = CrawlData(html);
                //Db.ExecuteTrans(t =>
                //{
                //    Dictionary<string, MiniApp> dictMiniApps = list.Key;
                //    Dictionary<string, MiniAppCategory> dictCategories = list.Value;
                //    foreach (MiniApp miniApp in list)
                //    {
                //        Db.Insert(miniApp, transaction: t);
                //    }
                //    return true;
                //});

            }



        }

        private KeyValuePair<Dictionary<string, MiniApp>, Dictionary<string, MiniAppCategory>> CrawlData(string html)
        {
            Dictionary<string, MiniApp> dictMiniApps = new Dictionary<string, MiniApp>();
            //List<MiniApp> list=new List<MiniApp>();
            Dictionary<string, MiniAppCategory> dictCategories = new Dictionary<string, MiniAppCategory>();
            List<MiniAppInfoCategory> listAppInfoCategories = new List<MiniAppInfoCategory>();
            HybridDictionary hybrid = JsonConvert.DeserializeObject<HybridDictionary>(html);
            var objects = hybrid["objects"] as JArray;
            foreach (JToken jToken in objects)
            {
                try
                {
                    MiniApp miniApp = new MiniApp();
                    miniApp.AppIcon = jToken["icon"]["image"].Value<string>();
                    miniApp.AppIntroduction = jToken["description"].Value<string>();
                    miniApp.AppName = jToken["name"].Value<string>();
                    //miniApp.Category = jToken["tag"].First["id"].Value<int>();
                    miniApp.Qrcode = jToken["qrcode"]["image"].Value<string>();
                    miniApp.CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    miniApp.UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    int appid = 0;
                    if (!Db.IsExist("where appname=@appname", "TD_AppInfo", new {@appname = miniApp.AppName}))
                    {
                        Db.Insert(miniApp);
                    }
                    // 查找ID
                    var m = Db.QueryModel<MiniApp>("select * from td_appinfo where appname=@appname",
                        new { appname = miniApp.AppName });

                    if (m != null)
                    {
                        appid = m.ID;
                    }
                    // 分组信息
                    JArray categoryArray = jToken["tag"] as JArray;
                    List<int> categoryList = new List<int>();
                    if (categoryArray != null)
                    {
                        foreach (JToken token in categoryArray)
                        {
                            try
                            {
                                var categoryname = token["name"].Value<string>();
                                MiniAppCategory miniAppCategory = new MiniAppCategory();
                                miniAppCategory.CategoryName = categoryname;
                                if (!Db.IsExist("where categoryname=@categoryname", "TD_Category",
                                    new { categoryname = categoryname }))
                                {
                                    Db.Insert(miniAppCategory);

                            
                                }
                                var c =
                                    Db.QueryModel<MiniAppCategory>(
                                        "select * from td_category where categoryname=@categoryname ",
                                        new { categoryname = categoryname });
                                if (c != null && !categoryList.Contains(c.ID))
                                {
                                    categoryList.Add(c.ID);
                                    MiniAppInfoCategory miniAppInfoCategory = new MiniAppInfoCategory();
                                    miniAppInfoCategory.AppId = appid;
                                    miniAppInfoCategory.CategoryId = c.ID;
                                    if (
                                        !Db.IsExist("where appid=@appid and categoryid=@categoryid ", "td_app_category",
                                            new { appid = appid, categoryid = c.ID }))
                                    {
                                        Db.Insert(miniAppInfoCategory);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                Crawl.Common.Common.Log.LogError(e.ToString());
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Crawl.Common.Common.Log.LogError(e.ToString());
                }
            }
            return new KeyValuePair<Dictionary<string, MiniApp>, Dictionary<string, MiniAppCategory>>(dictMiniApps, dictCategories);
        }

        /// <summary>
        /// 小程序信息
        /// </summary>
        [TableName("TD_AppInfo")]
        public class MiniApp
        {
            [PrimaryKey]
            [AutoIncrement]
            public int ID { get; set; }

            /// <summary>
            /// 名称
            /// </summary>
            public string AppName { get; set; }

            /// <summary>
            /// 简介
            /// </summary>
            public string AppIntroduction { get; set; }

            /// <summary>
            /// 图标
            /// </summary>
            public string AppIcon { get; set; }

            /// <summary>
            /// 二维码
            /// </summary>
            public string Qrcode { get; set; }

            /// <summary>
            /// 创建时间
            /// </summary>
            public string CreateTime { get; set; }
            public string UpdateTime { get; set; }
        }

        /// <summary>
        /// 分类
        /// </summary>
        [TableName("TD_Category")]
        public class MiniAppCategory
        {
            /// <summary>
            /// 自动编号
            /// </summary>
            [PrimaryKey]
            [AutoIncrement]
            public int ID { get; set; }

            /// <summary>
            /// 分类名称
            /// </summary>
            public string CategoryName { get; set; }

            /// <summary>
            /// 分类描述
            /// </summary>
            public string Detail { get; set; }
        }

        [TableName("TD_App_Category")]
        public class MiniAppInfoCategory
        {
            [PrimaryKey]
            [AutoIncrement]
            public int ID { get; set; }
            public int CategoryId { get; set; }

            public int AppId { get; set; }
        }
    }


}
